home *** CD-ROM | disk | FTP | other *** search
/ Aminet 28 / Aminet 28 (1998)(GTI - Schatztruhe)[!][Dec 1998].iso / Aminet / dev / misc / gms_config.lha / Config / config_init.c < prev    next >
Encoding:
Text File  |  1998-10-04  |  10.3 KB  |  389 lines

  1. /************************************************************************************
  2. ** Action: Free()
  3. ** Object: Config
  4. */
  5.  
  6. LIBFUNC void CON_Free(mreg(__a0) struct Config *Config)
  7. {
  8.   if (Config->prvBuffer)  { FreeMemBlock(Config->prvBuffer);  }
  9.   if (Config->prvEntries) { FreeMemBlock(Config->prvEntries); }
  10.   Public->OpenCount--;
  11. }
  12.  
  13. /************************************************************************************
  14. ** Action: Get()
  15. ** Object: Config
  16. */
  17.  
  18. LIBFUNC struct Config * CON_Get(mreg(__a0) struct Stats *Stats)
  19. {
  20.   struct Config *Config;
  21.  
  22.   if (Config = AllocMemBlock(sizeof(struct Config), MEM_RESOURCED|Stats->MemFlags)) {
  23.      Config->Head.ID      = ID_CONFIG;
  24.      Config->Head.Version = VER_CONFIG;
  25.      Public->OpenCount++;
  26.      return(Config);
  27.   }
  28.   else {
  29.      ErrCode(ERR_FAILED);
  30.      return(NULL);
  31.   }
  32. }
  33.  
  34. /************************************************************************************
  35. ** Action: Init()
  36. ** Object: Config
  37. */
  38.  
  39. LIBFUNC LONG CON_Init(mreg(__a0) struct Config *Config)
  40. {
  41.    OBJFile *File;
  42.    struct ConEntry *Entry;
  43.    WORD Array, Item, quote;
  44.    BYTE *Data, *Buffer, *Temp, *EData, *ATemp, *AData;
  45.    LONG i, line, items, FileSize, MaxLines, error;
  46.  
  47.    ATemp = NULL;
  48.    AData = NULL;
  49.    error = ERR_FAILED;
  50.  
  51.    if (File = Get(ID_FILE|GET_NOTRACK)) {
  52.       File->Source = Config->Source;
  53.       File->Flags  = FL_READ|FL_EXCLUSIVE;
  54.  
  55.       if (Init(File, NULL)) {
  56.          if ((FileSize = GetFSize(File)) > 0) {
  57.             if (AData = AllocPrivate(FileSize+2,MEM_UNTRACKED)) {
  58.                Read(File, AData, FileSize);
  59.                EData = AData + FileSize;
  60.             }
  61.             else goto exit;
  62.          }
  63.          else goto exit;
  64.       }
  65.       else goto exit;
  66.    }
  67.    else goto exit;
  68.  
  69.    DPrintF("3Config:","Data: $%x, EData: $%x, Size: %ld",AData,EData,FileSize);
  70.  
  71.    /* Process the file and get rid of PC carriage returns
  72.    ** (by replacing them with standard line feeds).
  73.    */
  74.  
  75.    MaxLines = 1;
  76.    for (i=0; i < FileSize; i++) {
  77.       if (AData[i] IS 10) {
  78.          MaxLines++;
  79.       }
  80.       else if (AData[i] IS 13) {
  81.          AData[i] = 10;
  82.       }
  83.    }
  84.  
  85.    /* Count the number of items to read */
  86.  
  87.    Data  = AData;
  88.    items = NULL;
  89.    while (Data < EData) {
  90.  
  91.       if (((*Data >= 'a') AND (*Data <= 'z')) OR
  92.           ((*Data >= 'A') AND (*Data <= 'Z')) OR
  93.           ((*Data >= '0') AND (*Data <= '9'))) {
  94.          items++;
  95.       }
  96.       else if (*Data IS '=') {
  97.          items++;
  98.          while (*Data != '[') {
  99.             while (*Data != 10) {
  100.                Data++;
  101.                if (Data >= EData) goto gotitems;
  102.             }
  103.             Data++;
  104.             if (Data >= EData) goto gotitems;
  105.          }
  106.       }
  107.  
  108.       while (*Data != 10) {
  109.          Data++;
  110.          if (Data >= EData) goto gotitems;
  111.       }
  112.       Data++;
  113.    }
  114.  
  115. gotitems:
  116.    DPrintF("Config:","I detected %ld items and arrays in the file.",items);
  117.  
  118.    Config->AmtEntries = NULL;
  119.  
  120.    /**** Allocate the Buffers ***/
  121.  
  122.    if ((ATemp = AllocPrivate(200,MEM_UNTRACKED)) IS NULL) {
  123.       ErrCode(ERR_MEMORY);
  124.       goto exit;
  125.    } 
  126.  
  127.    /* Buffer is allocated as:
  128.    **
  129.    **   Lines * (Longest Section Name + Longest Item Name + Longest Data)
  130.    */
  131.  
  132.    if ((Config->prvBuffer = AllocMemBlock((40+40+80)*MaxLines, Config->Head.Stats->MemFlags)) IS NULL) {
  133.       ErrCode(ERR_MEMORY);
  134.       goto exit;
  135.    }
  136.  
  137.    if ((Config->prvEntries = AllocMemBlock(sizeof(struct ConEntry) * items, Config->Head.Stats->MemFlags)) IS NULL) {
  138.       ErrCode(ERR_MEMORY);
  139.       goto exit;
  140.    }
  141.  
  142.    DPrintF("3Config:","Temp: $%x, Buffer: $%x, Entries: $%x",ATemp,Config->prvBuffer,Config->Entries);
  143.  
  144.    /*** Process now ***/
  145.  
  146.    Config->Entries = Config->prvEntries;
  147.    Data   = AData;
  148.    Buffer = Config->prvBuffer;
  149.    Entry  = Config->Entries;
  150.    line   = 1;
  151.  
  152.    /*** Find the first section ***/
  153.  
  154.    while (*Data != '[') {
  155.       if (*Data IS 10) line++;
  156.       Data++;
  157.       if (Data >= EData) {
  158.          DPrintF("!Config:","There are no Sections defined in this file!");
  159.          goto exit;
  160.       }
  161.    }
  162.  
  163.    DPrintF("3Config:","First section found at line %ld.",line);
  164.  
  165.    /*** FILE PROCESSOR ***/
  166.  
  167.    while (Data < EData) {
  168.       Array = FALSE;
  169.       Item  = FALSE;
  170.       while (*Data != '[') {
  171.  
  172.          /*** Item check (Must start with a letter or number) ***/
  173.  
  174.          if (((*Data >= 'a') AND (*Data <= 'z')) OR
  175.              ((*Data >= 'A') AND (*Data <= 'Z')) OR
  176.              ((*Data >= '0') AND (*Data <= '9'))) {
  177.  
  178.             if (Array IS FALSE) {
  179.                Item = TRUE;
  180.  
  181.                /*** Skip the section header that's in temp buffer ***/
  182.  
  183.                Temp = ATemp;
  184.                while (*Temp != NULL) Temp++;
  185.                Temp++;
  186.  
  187.                /*** Insert name of the Item just after the Section ***/
  188.  
  189.                while ((*Data != '=') AND (*Data != ' ') AND (*Data != 10)) {
  190.                   *Temp++ = *Data++;
  191.                   if (Data >= EData) goto okay;
  192.                }
  193.                *Temp = NULL;
  194.  
  195.                while (*Data IS ' ') { /* Skip past trailing spaces */
  196.                   Data++;
  197.                   if (Data >= EData) goto okay;
  198.                }
  199.  
  200.                /* Did an equal sign follow the Item name?  If not,
  201.                ** then there is an error at this line.
  202.                */
  203.  
  204.                if (*Data IS '=') {
  205.                   Data++;
  206.                   if (Data >= EData) goto okay;
  207.  
  208.                   while (*Data IS ' ') { /* Skip any leading spaces */
  209.                      Data++;
  210.                      if (Data >= EData) goto okay;
  211.                   }
  212.  
  213.                   if (*Data > 10) {
  214.  
  215.                      /*** Insert Section name ***/
  216.  
  217.                      Temp = ATemp;
  218.                      Entry->Section = Buffer;
  219.                      while (*Temp != NULL) {
  220.                         *Buffer++ = *Temp++;
  221.                      }
  222.                      *Buffer++ = NULL;
  223.  
  224.                      /*** Insert Item name ***/
  225.  
  226.                      Temp++;
  227.                      Entry->Item = Buffer;
  228.                      while (*Temp != NULL) {
  229.                         *Buffer++ = *Temp++;
  230.                      }
  231.                      *Buffer++ = NULL;
  232.  
  233.                      /* Insert the Item data.  This section also looks out
  234.                      ** for strings that have been defined using quotes (").
  235.                      ** These are forcibly removed.
  236.                      */
  237.  
  238.                      if (*Data IS '"') { Data++; quote = TRUE; } else quote = FALSE;
  239.                      Entry->Data = Buffer;
  240.                      while ((Data < EData) AND (*Data != 10)) {
  241.                         *Buffer++ = *Data++;
  242.                      }
  243.                      if (quote IS TRUE) {
  244.                         if (Buffer[-1] IS '"') Buffer[-1] = NULL; else *Buffer++ = NULL;
  245.                      }
  246.                      else *Buffer++ = NULL;
  247.  
  248.                      DPrintF("4Config:","Successfully read %s:%s.",Entry->Section,Entry->Item);
  249.                      Entry++; items--;
  250.                      Config->AmtEntries++;
  251.                      if (items IS NULL) goto okay;
  252.                   }
  253.                   else DPrintF("!Config:","Bad Item at line %ld.",line);
  254.                }
  255.                else DPrintF("!Config:","Bad Item at line %ld.",line);
  256.             }
  257.             else DPrintF("!Config:","Item found in array section at line %ld.",line);
  258.  
  259.             if (Data >= EData) goto okay;
  260.  
  261.             while (*Data != 10) {
  262.                Data++;
  263.                if (Data >= EData) goto okay;
  264.             }
  265.             line++;
  266.          }
  267.  
  268.          /*** Section holds array data ***/
  269.  
  270.          else if (*Data IS '=') {
  271.             if (Item IS FALSE) {
  272.                Data++;
  273.                if (Data >= EData) {
  274.                   DPrintF("!Config:","Bad array definition at line %ld.",line);
  275.                   goto okay;
  276.                }
  277.  
  278.                /*** INSERT INITIAL SECTION/ITEM INFORMATION ***/
  279.  
  280.                if (Array IS FALSE) {
  281.                   Temp = ATemp;
  282.                   Entry->Section = Buffer;
  283.                   while (*Temp != NULL) {
  284.                      *Buffer++ = *Temp++;
  285.                   }
  286.                   *Buffer++ = NULL;
  287.  
  288.                   Entry->Item = NULL;   /* Item Name of NULL */
  289.                   Entry->Data = Buffer;
  290.                   Array = TRUE;
  291.                }
  292.  
  293.                /*** INSERT DATA ***/
  294.  
  295.                if (*Data > 10) {
  296.                   while ((Data < EData) AND (*Data != 10)) {
  297.                      *Buffer++ = *Data++;
  298.                   }
  299.                }
  300.                else DPrintF("!Config:","Bad array definition at line %ld.",line);
  301.             }
  302.             else DPrintF("!Config:","Array found in Item section at line %ld.",line);
  303.  
  304.             if (Data >= EData) goto okay;
  305.  
  306.             while (*Data != 10) {
  307.                Data++;
  308.                if (Data >= EData) goto okay;
  309.             }
  310.             line++;
  311.          }
  312.          else if (*Data IS 10) line++;
  313.  
  314.          Data++;
  315.          if (Data >= EData) break;
  316.       }
  317.  
  318.       /* If the last section, was an array, we
  319.       ** must complete it here.
  320.       */
  321.  
  322.       if (Array IS TRUE) {
  323.          Array = FALSE;
  324.          DPrintF("4Config:","Successfully read array %s.",Entry->Section);
  325.          *Buffer++ = NULL;
  326.          Config->AmtEntries++;
  327.          Entry++;
  328.          items--;
  329.          if (items IS NULL) goto okay;
  330.       }
  331.  
  332.       /*** NEW SECTION ***/
  333.  
  334.       if (Data < EData) {
  335.          Temp = ATemp;
  336.          Data++;
  337.          if (Data >= EData) goto okay;
  338.          while ((*Data != ']') AND (*Data != 10)) {
  339.             *Temp++ = *Data++;
  340.             if (Data >= EData) {
  341.                DPrintF("!Config:","Bad section definition at line %ld.",line);
  342.                goto okay;
  343.             }
  344.          }
  345.          *Temp = NULL;
  346.  
  347.          DPrintF("4Config:","Found section \"%s\".",ATemp);
  348.  
  349.          while (*Data != 10) {
  350.             Data++;
  351.             if (Data >= EData) goto okay;
  352.          }
  353.  
  354.          line++;
  355.          Data++;
  356.       }
  357.    }
  358.  
  359. okay:
  360.    error = ERR_OK;
  361.    if (Array IS TRUE) {
  362.       DPrintF("4Config:","Successfully read array %s.",Entry->Section);
  363.       *Buffer = NULL;
  364.       Config->AmtEntries++;
  365.    }
  366.  
  367.    DPrintF("Config:","End of file reached, %ld lines read.",line);
  368.  
  369. exit:
  370.    if (File)  Free(File);
  371.    if (ATemp) FreeMemBlock(ATemp);
  372.    if (AData) FreeMemBlock(AData);
  373.    return(error);
  374. }
  375.  
  376. /************************************************************************************
  377. ** Action: Load()
  378. ** Object: Config
  379. */
  380.  
  381. LIBFUNC struct Config * CON_Load(mreg(__a0) struct File *Source)
  382. {
  383.   return(InitTags(NULL,
  384.     TAGS_CONFIG, NULL,
  385.     CFA_Source,  Source,
  386.     TAGEND));
  387. }
  388.  
  389.